﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using CanceledAppointmentUpdate.AppointmentScheduling;
//using CanceledAppointmentUpdate.UserManagement;
using System.Data.Odbc;
using System.Configuration;
using System.Threading;
using System.Threading.Tasks;
using System.Reflection;

namespace CanceledAppointmentUpdate
{
    public partial class CanceledAppointmentUpdate : Form
    {
        const string SystemCode = "LIVE";
        const string UserName = "ODBC";
        const string Password = "hotwire2011";
        List<FileType> FileTypeList = new List<FileType>();
        int count = 0;
        int total = 0;

        public CanceledAppointmentUpdate()
        {
            InitializeComponent();
            InitializeFileType();
            //InitializeReadFileBackgroundWorker();
            uxReadFileButton.Enabled = false;
            uxCancelReadingFileButton.Enabled = false;
            uxFileNameBox.Enabled = false;
        }

        public void InitializeFileType()
        {
            FileTypeList.Add(new FileType { TypeName = "Appointments", NumberOfFields = 19, NumberOfFieldsRequired = 14 });
        }

        //private void InitializeReadFileBackgroundWorker()
        //{
        //    readFileBackgroundWorker.WorkerReportsProgress = true;
        //    readFileBackgroundWorker.WorkerSupportsCancellation = true;
        //    readFileBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(readFileBackgroundWorker_RunWorkerCompleted);
        //    readFileBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(readFileBackgroundWorker_ProgressChanged);
        //    readFileBackgroundWorker.DoWork += new DoWorkEventHandler(readFileBackgroundWorker_DoWork);
        //}

        private void readFileBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            var worker = (BackgroundWorker)sender;
            ProcessRecord((CustomAppointment)e.Argument, worker, e);
        }

        void readFileBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            uxReadingFileProgressBar.Value = e.ProgressPercentage;
            uxFileStatusLabel.Text = "File is " + e.ProgressPercentage + "% " + "Complete";
            uxTotalDoneLabel.Text = count + "/" + total + " Files Processed";
        }

        void readFileBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

            if (e.Cancelled)
            {
                uxFileStatusLabel.Text = "Canceled!";
            }
            else if (e.Error != null)
            {
                uxFileStatusLabel.Text = "Error " + e.Error.Message;
            }
            else
            {
                if (e.Result != null)
                {
                    var response = (CustomResponse)e.Result;
                    uxResultTextBox.Text += "Appointment " + response.Appt_Unique_Id + ": " + response.ApptResponse.Message + "\r\n";
                }
                else
                    uxResultTextBox.Text += "Record Failed! ";
            }
        }

        private void ProcessRecord(CustomAppointment appointment, BackgroundWorker worker, DoWorkEventArgs e)
        {
            try
            {
                var response = FileWebService(appointment);
                //int percent = appointment.percent;
                var CustomResponse = new CustomResponse
                {
                    ApptResponse = response,
                    Appt_Unique_Id = appointment.UniqueId
                };
                count++;
                int percent = (int)(Math.Ceiling(((double) count / total) * 100));
                worker.ReportProgress(percent, appointment);
                e.Result = CustomResponse;
            }
            catch (Exception ex)
            {
                worker.CancelAsync();
            }
        }

        private List<CustomAppointment> ReadFile(string FileName)
        {
            try
            {
                string[] allText = File.ReadAllLines(FileName);
                return CreateAppointmentList(allText);
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        private List<CustomAppointment> CreateAppointmentList(string[] textFileLines)
        {
            FileType fileType = new FileType();
            fileType = FileTypeList.Find(f => f.TypeName == uxSelectFileType.Text.ToString());
            var appointmentList = new List<CustomAppointment>();
            var worker = new BackgroundWorker();

            for (int i = 0; i < textFileLines.Length; i++)
            {
                var tempObj = textFileLines[i].Split('|');
                if (tempObj.Length == fileType.NumberOfFields)
                {
                    var customApp = new CustomAppointment();
                    customApp.AppointmentSchedulingObj.Site = tempObj.ElementAt(0);
                    customApp.AppointmentSchedulingObj.ApptDate = Convert.ToDateTime(tempObj.ElementAt(1));
                    customApp.AppointmentSchedulingObj.ApptDateSpecified = !String.IsNullOrEmpty(tempObj.ElementAt(1));
                    customApp.AppointmentSchedulingObj.ApptStartTime = tempObj.ElementAt(2);
                    customApp.AppointmentSchedulingObj.ApptEndTime = tempObj.ElementAt(3);
                    customApp.AppointmentSchedulingObj.ServiceCode = tempObj.ElementAt(4);
                    customApp.AppointmentSchedulingObj.ApptStatus = tempObj.ElementAt(5);
                    customApp.AppointmentSchedulingObj.Location = tempObj.ElementAt(6);
                    customApp.AppointmentSchedulingObj.ClientID = tempObj.ElementAt(7);
                    customApp.AppointmentSchedulingObj.Episode = Convert.ToInt64( tempObj.ElementAt(8));
                    customApp.AppointmentSchedulingObj.EpisodeSpecified = !String.IsNullOrEmpty(tempObj.ElementAt(1));
                    customApp.AppointmentSchedulingObj.Program = tempObj.ElementAt(9);
                    customApp.AppointmentSchedulingObj.NumberOfClients = tempObj.ElementAt(10);
                    customApp.StaffId = tempObj.ElementAt(11);
                    if(!String.IsNullOrEmpty(tempObj[12]))
                        customApp.AppointmentSchedulingObj.MissedVisit = tempObj.ElementAt(12);
                    if(!String.IsNullOrEmpty(tempObj[13]))
                        customApp.AppointmentSchedulingObj.MissedVisitSvcCode = tempObj.ElementAt(13);
                    if(!String.IsNullOrEmpty(tempObj[14]))
                        customApp.AppointmentSchedulingObj.Confirmed = tempObj.ElementAt(14);
                    if(!String.IsNullOrEmpty(tempObj[15]))
                        customApp.AppointmentSchedulingObj.ReasonForFollowUp= tempObj.ElementAt(15);
                    if (!String.IsNullOrEmpty(tempObj[16]))
                        customApp.AppointmentSchedulingObj.ApptNotes = tempObj.ElementAt(16);
                    if (!String.IsNullOrEmpty(tempObj[17]))
                        customApp.AppointmentSchedulingObj.AdditionalServiceInformation = tempObj.ElementAt(17);
                    customApp.UniqueId = (tempObj.ElementAt(18)).ToString().Trim();
                    appointmentList.Add(customApp);
                }
            }
            total = appointmentList.Count();
            return appointmentList;
        }

        private WebServiceResponse FileWebService(CustomAppointment appointment)
        {
            var fileWebService = new AppointmentScheduling.AppointmentScheduling();
            var response = fileWebService.UpdateAppointment(SystemCode,
                UserName,
                Password,
                appointment.AppointmentSchedulingObj,
                appointment.StaffId,
                appointment.UniqueId);
            fileWebService.Dispose();

            return response;
        }

        private void uxSelectFileButton_Click(object sender, EventArgs e)
        {
            var openFileDialog = new OpenFileDialog();
            openFileDialog.InitialDirectory = "C:\\";
            openFileDialog.Filter = "txt files (*.txt)|*.txt";
            openFileDialog.FilterIndex = 1;
            openFileDialog.RestoreDirectory = true;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                uxFileNameBox.Text = openFileDialog.FileName;
                uxReadFileButton.Enabled = true;
            }
            else
            {
                MessageBox.Show("Error: cannot read file, please try again");
            }
        }

        private void uxReadFileButton_Click(object sender, EventArgs e)
        {
            uxFileStatusLabel.Text = string.Empty;
            this.uxReadFileButton.Enabled = false;
            this.uxCancelReadingFileButton.Enabled = true;
            var appointmentList = ReadFile(uxFileNameBox.Text);
            

            foreach (var appointment in appointmentList)
            {
                var bgw = CreateBgw();
                if (!bgw.IsBusy)
                {
                    bgw.RunWorkerAsync(appointment);
                }
            }
            //uxResultTextBox.Text += "Loop finished";
        }

        private BackgroundWorker CreateBgw()
        {
            var bgw = new BackgroundWorker();
            bgw.DoWork += new DoWorkEventHandler(readFileBackgroundWorker_DoWork);
            bgw.ProgressChanged +=new ProgressChangedEventHandler(readFileBackgroundWorker_ProgressChanged);
            bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(readFileBackgroundWorker_RunWorkerCompleted);
            bgw.WorkerSupportsCancellation = true;
            bgw.WorkerReportsProgress = true;
            return bgw;
        }

        private void uxCancelReadingFile_Click(object sender, EventArgs e)
        {
            this.uxCancelReadingFileButton.Enabled = false;
            this.uxReadFileButton.Enabled = true;
            if (readFileBackgroundWorker.WorkerSupportsCancellation == true)
            {
                readFileBackgroundWorker.CancelAsync();
            }
        }
    }
}
